import { omapi } from '@kit.ConnectivityKit';
import { Log } from '../utils/Log';
import { BusinessError } from '@kit.BasicServicesKit';

class SmartCard {

  private static instance:SmartCard
  private  seService : omapi.SEService
  private seReaders : omapi.Reader[]
  private seSession : omapi.Session
  private seChannel : omapi.Channel
  aidArray : number[] = [0xA0, 0x00, 0x00, 0x00, 0x03, 0x10, 0x10]
  p2 : number = 0x00

  public static getInstance() :SmartCard  {
    if (null == SmartCard.instance){
      SmartCard.instance = new SmartCard();
    }
    return SmartCard.instance;
  }

  constructor() {
    if (!this.checkOMA){
      return
    }
    omapi.createService().then((service) => {
      this.seService = service
      Log.d('createService:' + service.isConnected());
    })
    // this.seService = omapi.newSEService("serviceState", (ServiceState) => {
    //   let state:string = JSON.stringify(ServiceState)
    //   Log.d(`omapi.newSEService serviceState:${state}`);
    // });
  }

  checkOMA() : boolean {
    // 判断设备是否支持NFC能力
    if (!canIUse("SystemCapability.Communication.SecureElement")) {
      Log.e('oma unavailable.');
      return false
    }
    return true
  }

  isSeServiceConnected(){
    return this.seService !== undefined && this.seService?.isConnected()
  }

  openChannel(aidArray:number[] ,p2:number) : Uint8Array {
    this.seReaders = this.seService.getReaders()
    if (this.seReaders != null && this.seReaders.length > 0){
      let reader:omapi.Reader = this.seReaders[0]
      this.seSession = reader.openSession()
      if (this.seSession != null){
        this.seSession.openLogicalChannel(aidArray, p2, (error, data:omapi.Channel) => {
          if (error) {
            Log.e(`openLogicalChannel:${JSON.stringify(error)}`);
          } else {
            this.seChannel = data;
            //channel应该包含fci信息，待查证，
            return this.seChannel.getSelectResponse()
          }
        })
      }
    }
    return;
  }

  transceive(cmd:number[]) : number[] {
    if (this.isSeServiceConnected() && !this.seChannel?.isClosed()){
      Log.d(`transceive cmd --> ${cmd}`);
      this.seChannel.transmit(cmd).then((response) => {
        Log.e(`transceive resp:${JSON.stringify(response)}`);
        return response
      }).catch((error : BusinessError) => {
        Log.e(`transceive:${JSON.stringify(error)}`);
      })
    } else {
      Log.e(`transceive --> channel not open:`);
    }
    return
  }

  closeChannel() : void {
    if (this.isSeServiceConnected && !this.seChannel?.isClosed()){
      this.seChannel.close()
    }
  }

  closeSeService() : void {
    if (this.isSeServiceConnected){
      this.closeChannel()
      if (!this.seSession?.isClosed()){
        this.seSession.close()
      }
      this.seService.shutdown()
    }
  }
}

let smartCard = SmartCard.getInstance()
export default smartCard as SmartCard